package com.gpipe.dirwatcher;

import java.io.File;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.gpipe.dbwriter.LoadDataByDirectory;
import com.gpipe.dirwatcherRealtime.DirectorySnapshotRealtime;
import com.gpipe.dirwatcherRealtime.InitialMethod;
import com.gpipe.properties.InputProperties;
import com.gpipe.tools.GpipeInit;

public class FillDataDirectoryWatcher extends AbstractResourceWatcher {
	/**
	 * The current map of files and their timestamps (String fileName => Long
	 * lastMod)
	 */
	private Map currentFiles = new HashMap();

	// Fill Data :the end filename of one day
	private String endFileName = null;

	// /**
	// * The basestations and their longtitude latitude (String lac|ci =>
	// * String longtitude|latitude)
	// */
	// private Map basestation = new HashMap();

	/**
	 * The directory to watch.
	 */
	private String directory;

	/**
	 * Fill data:Interval to pass.
	 */
	private static int fillInterval;

	/**
	 * The map of last recorded files and their timestamps (String fileName =>
	 * Long lastMod)
	 */
	private Map prevFiles = new HashMap();

	/**
	 * Constructor that takes the directory to watch.
	 * 
	 * @param directoryPath
	 *            the directory to watch
	 * @param intervalSeconds
	 *            The interval to use when monitoring this directory. I.e., ever
	 *            x seconds, check this directory to see what has changed.
	 * @throws IllegalArgumentException
	 *             if the argument does not map to a valid directory
	 */
	public FillDataDirectoryWatcher(String directoryPath, int intervalSeconds)
			throws IllegalArgumentException {

		// Get the common thread interval stuff set up.
		super(intervalSeconds, directoryPath + " interval watcher.");

		// Check that it is indeed a directory.
		File theDirectory = new File(directoryPath);

		if (theDirectory != null && !theDirectory.isDirectory()) {

			// This is bad, so let the caller know
			String message = "The path " + directory
					+ " does not represent a valid directory.";
			throw new IllegalArgumentException(message);

		}
		// Else all is well so set this directory and the interval
		this.directory = directoryPath;

		try {
			InputProperties.basestation.putAll(new InitialMethod()
					.getBasestation());
			InputProperties.baseRegion.putAll(new InitialMethod()
					.getBaseRegion());
			InputProperties.inputdataConf.putAll(new InitialMethod()
					.getInputdataConf());
			if (InputProperties.inputdataConf.get("lac|ci") == null
					|| InputProperties.inputdataConf.get("lac|ci").split("\\|",
							-1).length != 2
					|| InputProperties.inputdataConf.get("nbr") == null) {
				System.err
						.println("The settings of lac|ci or lang|la were wrong.");
				System.exit(0);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * pc_test:2016-07-27 10:03:23:Initialize the basestation file. 2016-07-27
	 * 10:03:23:Start to monitor E:\testLog\jw_test_file\realtime 2016-07-27
	 * 10:03:56:Start to writedata into mysql 2016-07-27 10:06:48:Finish writing
	 * data into mysql
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		// local test
//		 args = new String[] { "E:\\testLog\\jw_test_file\\filldata", "900" };

		// Monitor c:/temp every 5 seconds
		if (args.length < 2) {
			System.err.println("useage <dirpath> <interval>");
			System.exit(0);
		}
		fillInterval = Integer.parseInt(args[1]);
		FillDataDirectoryWatcher dw = new FillDataDirectoryWatcher(args[0],
				Integer.parseInt(args[1]));
		dw.addListener(new FileListener());
		dw.start();
	}

	/**
	 * Start the monitoring of this directory.
	 */
	public void start() {

		// Since we're going to start monitoring, we want to take a snapshot of
		// the
		// current directory to we have something to refer to when stuff
		// changes.
		takeSnapshot();

		// And start the thread on the given interval
		super.start();

		// And notify the listeners that monitoring has started
		File theDirectory = new File(directory);
		monitoringStarted(theDirectory);
	}

	/**
	 * Stop the monitoring of this directory.
	 */
	public void stop() {

		// And start the thread on the given interval
		super.stop();

		// And notify the listeners that monitoring has started
		File theDirectory = new File(directory);
		monitoringStopped(theDirectory);
	}

	/**
	 * Store the file names and the last modified timestamps of all the files
	 * and directories that exist in the directory at this moment.
	 */
	private void takeSnapshot() {
		// Set the last recorded snap shot to be the current list
		prevFiles.clear();
		prevFiles.putAll(currentFiles);
		// And get a new current state with all the files and directories
		currentFiles.clear();
		File theDirectory = new File(directory);
		String[] files = theDirectory.list();
		if (files != null && files.length > 0) {
			for (String _f : files) {
				if (_f.contains("interface_")) {
					String _filePath = GpipeInit.changeToDir(directory) + _f;
					File _file = new File(_filePath);
					if (_file.isFile()) {
						currentFiles.put(_file.getAbsolutePath(), new Long(
								_file.lastModified()));
					}
				}
				/*
				 * else if(_file.isDirectory()){ getSnapFiles(_filePath); }
				 */
			}
		}
	}

	/*
	 * @SuppressWarnings("unchecked") private void getSnapFiles(String
	 * _filePath){ File _directory = new File(_filePath); String[] children =
	 * _directory.list(); if(children!=null&&children.length>0){ for (int i = 0;
	 * i < children.length; i++) { String _fPath =
	 * GpipeInit.changeToDir(_filePath) + children[i]; File _file = new
	 * File(_fPath);; if(_file.isFile()){
	 * currentFiles.put(_file.getAbsolutePath(), new
	 * Long(_file.lastModified())); }else if(_file.isDirectory()){
	 * getSnapFiles(_fPath); } } } }
	 */

	/**
	 * Check this directory for any changes and fire the proper events.
	 */
	@SuppressWarnings("unchecked")
	protected void doInterval() {
		// Fill Data:cancel the interval sleep because of fill data.
		super.changeFD();

		// Fill Data:if one day file finish dueling then stop the program.
		if (!(endFileName == null)
				&& (DirectorySnapshot.firstFileName == endFileName || DirectorySnapshot.firstFileName == GpipeInit
						.returnBiggerStr(DirectorySnapshot.firstFileName,
								endFileName))) {
			GpipeInit.writeLogs("--##--stop the program!");
			super.stop();
		}

		// Take a snapshot of the current state of the dir for comparisons
		takeSnapshot();

		DirectorySnapshotRealtime.oneHourFiles = new HashMap<String, String>();

		// Fill Data:according to the data of one day,divide them by interval
		// and put then interval's data into DirectorySnapshot.files.

		if (!DirectorySnapshot.lastFileName.contains(".cdr")) {

			// The last filename in the currentFiles
			// Fill Data:in this part it use for storing the startFileName of
			// every interval
			DirectorySnapshot.lastFileName = null;

			// The first filename in the currentFiles
			DirectorySnapshot.firstFileName = null;

			// Find the last filename in the currentFiles
			Iterator cuIt = currentFiles.keySet().iterator();
			while (cuIt.hasNext()) {
				String fileName = (String) cuIt.next();
				if (DirectorySnapshot.firstFileName == null
						&& endFileName == null) {
					DirectorySnapshot.firstFileName = fileName;
					endFileName = fileName;
				} else {
					DirectorySnapshot.firstFileName = GpipeInit
							.returnSmallerStr(DirectorySnapshot.firstFileName,
									fileName);
					endFileName = GpipeInit.returnBiggerStr(
							endFileName, fileName);
				}
			}

			DirectorySnapshot.lastFileName = GpipeInit.plusTheInterval(
					DirectorySnapshot.firstFileName, fillInterval, ".cdr.gz");

		} else {
			
			DirectorySnapshot.firstFileName = DirectorySnapshot.lastFileName;
			DirectorySnapshot.lastFileName = GpipeInit.plusTheInterval(
					DirectorySnapshot.firstFileName, fillInterval, ".cdr.gz");
		}
		GpipeInit.writeLogs("--&&--endFileName==" + endFileName);
		GpipeInit.writeLogs("--&&--lastFileName:"
				+ DirectorySnapshot.lastFileName);
		GpipeInit.writeLogs("--&&--firstFileName:"
				+ DirectorySnapshot.firstFileName);

		// Iterate through the map of current files and compare
		// them for differences etc...and add filename into
		// DirectorySnapshot.file
		Iterator currentIt = currentFiles.keySet().iterator();
		DirectorySnapshot.files = new HashMap();
		while (currentIt.hasNext()) {

			String fileName = (String) currentIt.next();
			Long lastModified = (Long) currentFiles.get(fileName);

			// If this file is between now and one hour before,then
			// it's been added
			try {
				if (GpipeInit.inOneHourFD(DirectorySnapshot.lastFileName,
						fileName, ".cdr.gz")) {
					DirectorySnapshotRealtime.oneHourFiles.put(fileName,
							fileName);
				}
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// If the fileName between the firstFileName and lastFileName,
			// it's been added
			try {
				if (GpipeInit.betweenTwoFN(DirectorySnapshot.firstFileName,
						DirectorySnapshot.lastFileName, fileName, ".cdr.gz")) {
					DirectorySnapshot.addFile(fileName);
				}
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		// Print all static propertitys
		GpipeInit.writeLogs("--&&--Print all static propertitys----");
		System.out.println("--baseNbrArea:"
				+ DirectorySnapshotRealtime.baseNbrArea.size());
		System.out.println("--interval:"
				+ DirectorySnapshotRealtime.statInterval);
		System.out.println("--longLaArea:"
				+ DirectorySnapshotRealtime.longLaArea.size());
		System.out.println("--midResults:"
				+ DirectorySnapshotRealtime.midResults.size());
		System.out.println("--NbrArea:"
				+ DirectorySnapshotRealtime.NbrArea.size());
		System.out.println("--nbrLongLaRes:"
				+ DirectorySnapshotRealtime.nbrLongLaRes.size());
		System.out.println("--oneHourFiles:"
				+ DirectorySnapshotRealtime.oneHourFiles.size());
		System.out.println("--records:"
				+ DirectorySnapshotRealtime.records.size());
		System.out.println("--results:"
				+ DirectorySnapshotRealtime.results.size());

		// The Entrance:find the new files and
		// begin to duel with them
		System.out.println("--&&--DirectorySnapshot.files.size()="
				+ DirectorySnapshot.files.size());
		if (DirectorySnapshot.files.size() > 0) {
			GpipeInit.writeLogs("--------Process begin!--------");
			LoadDataByDirectory loadDataByDirectory = new LoadDataByDirectory();
			loadDataByDirectory.MysqlRealtime();// zhengrx
		}

		// Now we need to iterate through the list of previous files and
		// see if any that existed before don't exist anymore

		Iterator prevIt = prevFiles.keySet().iterator();

		while (prevIt.hasNext()) {

			String fileName = (String) prevIt.next();

			// If this file did exist before, but it does not now, then
			// it's been deleted
			if (!currentFiles.containsKey(fileName)) {
				DirectorySnapshot.removeFile(fileName);
				resourceDeleted(fileName);
			}
		}
	}
}
